use crate::parser::{Program, Node};
use std::fmt::Write;

fn indent(level: usize) -> String {
    " ".repeat(level * 4)
}

pub fn format_program(program: &Program) -> String {
    let mut out = String::new();
    for item in &program.items {
        match item {
            Node::ConstDecl { defs } => {
                // 保持多定义在一行
                if !defs.is_empty() {
                    writeln!(out, "const int {};", defs.join(", ")).ok();
                }
            }
            Node::VarDecl { defs } => {
                if !defs.is_empty() {
                    writeln!(out, "int {};", defs.join(", ")).ok();
                }
            }
            Node::FuncDef { rettype, name, params, body } => {
                let params_text = if params.is_empty() {
                    "".to_string()
                } else {
                    params.join(", ")
                };
                writeln!(out, "{} {}({}) {{", rettype, name, params_text).ok();
                format_node(body, 1, &mut out);
                writeln!(out, "}}").ok();
            }
            _ => {
                // 其他节点，直接递归格式化
                format_node(item, 0, &mut out);
            }
        }
    }
    out.trim_end().to_string()
}

fn format_node(node: &Node, level: usize, out: &mut String) {
    match node {
        Node::Block(items) => {
            for it in items {
                match it {
                    Node::ConstDecl { defs } => {
                        if !defs.is_empty() {
                            writeln!(out, "{}const int {};", indent(level), defs.join(", ")).ok();
                        }
                    }
                    Node::VarDecl { defs } => {
                        if !defs.is_empty() {
                            writeln!(out, "{}int {};", indent(level), defs.join(", ")).ok();
                        }
                    }
                    Node::Stmt(s) => {
                        writeln!(out, "{}{}", indent(level), s.trim()).ok();
                    }
                    Node::Block(inner) => {
                        writeln!(out, "{}{{", indent(level)).ok();
                        for i in inner {
                            format_node(i, level + 1, out);
                        }
                        writeln!(out, "{}}}", indent(level)).ok();
                    }
                    _ => {
                        // 不输出调试信息，避免 extra output
                    }
                }
            }
        }
        Node::Stmt(s) => {
            writeln!(out, "{}{}", indent(level), s.trim()).ok();
        }
        _ => {
            // 不输出调试信息
        }
    }
}
